package sany.iec.service.svg;

import com.serotonin.modbus4j.BasicProcessImage;
import com.serotonin.modbus4j.ModbusSlaveSet;
import com.serotonin.modbus4j.ProcessImageListener;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.ip.tcp.TcpSlave;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import sany.iec.config.ModbusSalveConfig;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @Author : 托马斯
 * @Date : 2025/7/3 10:31
 * @Description :
 */
@Service
@Slf4j
public class SvgDataService {

    @Value("${modbus.svg.id}")
    private int id;


    @Resource
    private ModbusSalveConfig modbusSalveConfig;

    public static Boolean FLAG = true;

    ModbusSlaveSet modbus = null;

    @PostConstruct
    public void init() throws ModbusInitException, InterruptedException {
        //向过程影像区添加数据
        new Thread(() -> {
            while (true) {
                if (FLAG) {
                    try {
                        log.info("Modbus init success, port: {}, id: {}", modbusSalveConfig.getPort(), id);
                        modbus = new TcpSlave(modbusSalveConfig.getPort(), false);
                        modbus.addProcessImage(getModscanProcessImage(id));
                        modbus.start();
                    } catch (ModbusInitException e) {
                        log.error("Modbus init error", e);
                    }
                }
            }
        }).start();
        Thread.sleep(20000);
        FLAG = false;
        log.info("FLAG= {}", FLAG);
        modbus.stop();
        Thread.sleep(20000);
        FLAG = true;
        log.info("FLAG= {}", FLAG);
    }

    private BasicProcessImage getModscanProcessImage(int slaveId) {
        /* 初始化过程影像区 */
        BasicProcessImage processImage = new BasicProcessImage(slaveId);
        /* 设置无效地址的默认值为Short类型的最大值 */
        // processImage.setInvalidAddressValue(Short.MAX_VALUE);

        /* 初始化过程影像区各个数值为0 */
        for (int i = 0; i < 30000; i++) {
            processImage.setCoil(i, Math.random() > 0.5);
            processImage.setInput(i, Math.random() > 0.5);
            processImage.setHoldingRegister(i, (short) (Math.random() * 100));
            processImage.setInputRegister(i, (short) (Math.random() * 100));
        }
        /* 为影像区添加监听 */
        processImage.addListener(new BasicProcessImageListener());
        return processImage;
    }

    private static class BasicProcessImageListener implements ProcessImageListener {

        @Override
        public void coilWrite(int i, boolean b, boolean b1) {

        }

        @Override
        public void holdingRegisterWrite(int offset, short oldValue, short newValue) {
            System.out.println("Register at " + offset + "," + "change " + oldValue + " to " + newValue);
        }
    }

}
